﻿using System;
using System.Linq;
using System.Web.UI.WebControls;

namespace ECommerce
{
	public partial class OrderConfirm : BasePage
	{
		private Service.IOrderService _OrderService;
		private Service.IProductService _ProductService;
		private Service.IShippingMethodService _ShippingMethodService;

		private Data.Entity.Order _TheOrder;

		private decimal _ProductTotalPrice;

		private decimal _ShippingMethodCosts;

		public decimal ShippingMethodCosts
		{
			get
			{
				if (_ShippingMethodCosts > 0)
				{
					return _ShippingMethodCosts;
				}

				if (TheOrder != null)
				{
					if (TheOrder.ShippingStateProvinceID.Value > 0 && TheOrder.ShippingMethodID.Value > 0)
					{
						if (_ShippingMethodService == null)
						{
							_ShippingMethodService = new Service.ShippingMethodService();
						}

						var shipping = _ShippingMethodService.GetShippingByStateAndProvinceByProvince(TheOrder.ShippingStateProvinceID.Value);

						if (shipping == null)
						{
							_ShippingMethodCosts = decimal.Zero;
						}
						else
						{
							var cost = (from s in shipping
										where s.ShippingMethodID.Equals(TheOrder.ShippingMethodID.Value)
										select s.TransportCosts).FirstOrDefault();

							_ShippingMethodCosts = cost;
						}
					}
					else
					{
						_ShippingMethodCosts = decimal.Zero;
					}
				}
				else
				{
					_ShippingMethodCosts = decimal.Zero;
				}

				return _ShippingMethodCosts;
			}
			set
			{
				_ShippingMethodCosts = value;
			}
		}

		public int TheOrderID
		{
			get
			{
				return CommonHelper.QueryStringInt("orderid");
			}
		}

		public Data.Entity.Order TheOrder
		{
			get
			{
				if (_TheOrder != null)
				{
					return _TheOrder;
				}

				if (TheOrderID > 0)
				{
					if (_OrderService == null)
					{
						_OrderService = new Service.OrderService();
					}

					_TheOrder = _OrderService.GetTheOrderByOrderID(TheOrderID);
				}

				return _TheOrder;
			}
		}

		public decimal ProductTotalPrice
		{
			get
			{
				if (_ProductTotalPrice > 0)
				{
					return _ProductTotalPrice;
				}
				else
				{
					if (TheOrderID > 0)
					{
						if (_OrderService == null)
						{
							_OrderService = new Service.OrderService();
						}

						if (_ProductService == null)
						{
							_ProductService = new Service.ProductService();
						}

						_ProductTotalPrice = (from op in _OrderService.GetOrderProductMappingByOrder(TheOrderID)
								join prod in _ProductService.GetProductsByLanguage(TheOrder.UserLanguageID) on op.ProductID equals prod.ProductID
								select new
								{
									ProductID = prod.ProductID,
									ListPrice = prod.ListPrice,
									Quantity = op.Quantity
								}).Sum(e => e.Quantity * e.ListPrice).GetValueOrDefault();

						return _ProductTotalPrice;
					}
					else
					{
						return decimal.Zero;
					}
				}
			}
			set
			{
				_ProductTotalPrice = value;
			}
		}

		protected void Page_Load(object sender, EventArgs e)
		{
			if (!IsPostBack)
			{
				BindTheOrderData();
			}
		}

		protected void Page_PreRender(object sender, EventArgs e)
		{
			ButtonPay.Text = GetLocalResourceString("Ecommerce.ButtonPay.Text");

			this.Title = GetLocalResourceString("PageTitle.OrderConfirm");

			this.LOrderNumber.Text = GetLocalResourceString("OrderConfirm.OrderNumber.Label");
			this.LShippingAddressTitle.Text = GetLocalResourceString("OrderConfirm.ShippingAddress.Title");
			this.LShippingMethodTitle.Text = GetLocalResourceString("OrderConfirm.ShippingMethod.Title");
			this.LPaymentMethodTitle.Text = GetLocalResourceString("OrderConfirm.PaymentMethod.Title");
			this.LOrderRemarkTitle.Text = GetLocalResourceString("OrderConfirm.OrderRemark.Title");
			this.LOrderProductListTitle.Text = GetLocalResourceString("OrderSummary.OrderProductListTitle");
			this.LProductPriceSummaryLabel.Text = GetLocalResourceString("OrderConfirm.ProductPriceSummaryLable");
			this.LShippingMethodPriceSummaryLabel.Text = GetLocalResourceString("OrderConfirm.ShippingMethodPriceSummaryLabel");
			this.LCashTicketCostLabel.Text = GetLocalResourceString("OrderConfirm.CashTicketCostLabel");
			this.LPriceSummaryLable.Text = GetLocalResourceString("ShoppingCart.PriceSummaryLable");
		}

		protected void ButtonPay_Click(object sender, EventArgs e)
		{
			if (TheOrder.PaymentMethodName.Equals("支付宝"))
			{
				var thePaymentUrl = BuildTheAliPaymentUrl();

				Response.Redirect(thePaymentUrl);
			}
		}

		protected void GridOrderProduct_RowDataBound(object sender, GridViewRowEventArgs e)
		{
			if (e.Row.RowType == DataControlRowType.Header)
			{
				e.Row.Cells[0].Text = GetLocalResourceString("ShoppingCart.ProdNameCellHeaderText");
				e.Row.Cells[1].Text = GetLocalResourceString("ShoppingCart.QuantityCellHeaderText");
				e.Row.Cells[2].Text = GetLocalResourceString("ShoppingCart.ListPriceCellHeaderText");
			}
		}

		private void BindTheOrderData()
		{
			if (TheOrderID > 0)
			{
				if (TheOrder != null)
				{
					this.LiteralOrderNumber.Text = TheOrder.OrderNumber;
					this.LiteralAddressDetail.Text = TheOrder.ShippingCountry + " " + TheOrder.ShippingStateProvince + " " + TheOrder.ShippingCity + " " + TheOrder.ShippingAddress1;
					this.LiteralMobileNumber.Text = TheOrder.ShippingMobileNumber;
					this.LiteralOrderPriceSummary.Text = string.Empty;
					this.LiteralOrderRemark.Text = TheOrder.Remark;
					this.LiteralPaymentMethod.Text = TheOrder.PaymentMethodName;
					this.LiteralPhoneNumber.Text = TheOrder.ShippingPhoneNumber;
					this.LiteralShippingMethod.Text = GetLocalResourceString("ShippingMethod." + TheOrder.ShippingMethod);

					decimal shippingCost = GetShippingMethodCost(TheOrder.ShippingStateProvinceID.GetValueOrDefault(), TheOrder.ShippingMethodID.GetValueOrDefault());

					this.ShippingMethodCosts = shippingCost;

					this.LiteralShippingMethodPriceSummary.Text = shippingCost.ToString("c2");
					this.LiteralUserName.Text = TheOrder.ShippingLastName + TheOrder.ShippingFirstName;

					this.LiteralCashTicketCost.Text = TheOrder.OrderDiscount.Value.ToString("c2");

					decimal productPriceSum = BindProductData(TheOrder.OrderID, TheOrder.UserLanguageID);

					this.LiteralOrderPriceSummary.Text = (shippingCost + productPriceSum - TheOrder.OrderDiscount.Value).ToString("c2");
					this.ProductTotalPrice = productPriceSum;
				}
			}
		}

		private decimal GetShippingMethodCost(int stateProvinceID, int shippingMethodID)
		{
			if (stateProvinceID > 0 && shippingMethodID > 0)
			{
				if (_ShippingMethodService == null)
				{
					_ShippingMethodService = new Service.ShippingMethodService();
				}

				var shipping = _ShippingMethodService.GetShippingByStateAndProvinceByProvince(stateProvinceID);
				decimal cost = decimal.Zero;

				if (shipping != null)
				{
					cost = (from s in shipping
							where s.ShippingMethodID.Equals(shippingMethodID)
							select s.TransportCosts).FirstOrDefault();
				}

				return cost;
			}
			else
			{
				return decimal.Zero;
			}
		}

		private decimal BindProductData(int orderID, int languageID)
		{
			if (_OrderService == null)
			{
				_OrderService = new Service.OrderService();
			}

			if (_ProductService == null)
			{
				_ProductService = new Service.ProductService();
			}

			var orderProductMappings = (from op in _OrderService.GetOrderProductMappingByOrder(orderID)
										join prod in _ProductService.GetProductsByLanguage(languageID) on op.ProductID equals prod.ProductID
										select new
										{
											ProductID = prod.ProductID,
											ProductName = prod.Name,
											ListPrice = prod.ListPrice,
											Quantity = op.Quantity
										});

			if (orderProductMappings != null && orderProductMappings.Count() > 0)
			{
				GridOrderProduct.DataSource = orderProductMappings;
				GridOrderProduct.DataBind();

				var sumProductPrice = orderProductMappings.Sum(e => e.Quantity * e.ListPrice);

				LiteralProductPriceSummary.Text = sumProductPrice.GetValueOrDefault().ToString("c2");

				return sumProductPrice.GetValueOrDefault();
			}

			return decimal.Zero;
		}

		private string BuildTheAliPaymentUrl()
		{
			///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的///////////////////////////
			string partner = "2088302091633148";                                     //合作身份者ID
			string key = "rs8e8p90hciw3rlwqtvxjhqfu3s0f6kz";                         //安全检验码
			string seller_email = "shanghaijunjun@126.com";                             //签约支付宝账号或卖家支付宝帐户
			string input_charset = "utf-8";												//字符编码格式 目前支持 gbk 或 utf-8
			string notify_url = "http://godbuying.com/Alipay/Notify.aspx";				//交易过程中服务器通知的页面 要用 http://格式的完整路径，不允许加?id=123这类自定义参数
			string return_url = "http://godbuying.com/Alipay/Return.aspx";				//付完款后跳转的页面 要用 http://格式的完整路径，不允许加?id=123这类自定义参数
			string show_url = "http://godbuying.com/Customer/OrderDetail.aspx";                     //网站商品的展示地址，不允许加?id=123这类自定义参数
			string sign_type = "MD5";													//加密方式 不需修改

			////////////////////////////////////////////////////////////////////////////////////////////////////

			///////////////////////以下参数是需要通过下单时的订单数据传入进来获得////////////////////////////////
			//必填参数
			string out_trade_no = TheOrder.OrderNumber;									//请与贵网站订单系统中的唯一订单号匹配
			string subject = "至高之选-订单编号:" + TheOrder.OrderNumber;														//订单名称，显示在支付宝收银台里的“商品名称”里，显示在支付宝的交易管理的“商品名称”的列表里。
			string body = TheOrder.Remark;												//订单描述、订单详细、订单备注，显示在支付宝收银台里的“商品描述”里
			string price = TheOrder.OrderTotal.Value.ToString("f2");                  		                //订单总金额，显示在支付宝收银台里的“商品单价”里

			string logistics_fee = ShippingMethodCosts.ToString();                  				//物流费用，即运费。
			string logistics_type = TheOrder.ShippingMethod;				                //物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
			string logistics_payment = "BUYER_PAY";            							//物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

			string quantity = "1";              										//商品数量，建议默认为1，不改变值，把一次交易看成是一次下订单而非购买一件商品。

			//扩展参数——买家收货信息（推荐作为必填）
			//该功能作用在于买家已经在商户网站的下单流程中填过一次收货信息，而不需要买家在支付宝的付款流程中再次填写收货信息。
			//若要使用该功能，请至少保证receive_name、receive_address有值
			string receive_name = TheOrder.ShippingLastName + TheOrder.ShippingFirstName;			                    //收货人姓名，如：张三
			string receive_address = TheOrder.ShippingCountry + TheOrder.ShippingStateProvince + TheOrder.ShippingCity + TheOrder.ShippingAddress1;			                //收货人地址，如：XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号
			string receive_zip = TheOrder.ShippingZipPostalCode;                  			    //收货人邮编，如：123456
			string receive_phone = TheOrder.ShippingPhoneNumber;                		    //收货人电话号码，如：0571-81234567
			string receive_mobile = TheOrder.ShippingMobileNumber;               		    //收货人手机号码，如：13312341234

			//扩展参数——第二组物流方式
			//物流方式是三个为一组成组出现。若要使用，三个参数都需要填上数据；若不使用，三个参数都需要为空
			//有了第一组物流方式，才能有第二组物流方式，且不能与第一个物流方式中的物流类型相同，
			//即logistics_type="EXPRESS"，那么logistics_type_1就必须在剩下的两个值（POST、EMS）中选择
			string logistics_fee_1 = string.Empty;                				    //物流费用，即运费。
			string logistics_type_1 = string.Empty;               					//物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
			string logistics_payment_1 = string.Empty;           		                //物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

			//扩展参数——第三组物流方式
			//物流方式是三个为一组成组出现。若要使用，三个参数都需要填上数据；若不使用，三个参数都需要为空
			//有了第一组物流方式和第二组物流方式，才能有第三组物流方式，且不能与第一组物流方式和第二组物流方式中的物流类型相同，
			//即logistics_type="EXPRESS"、logistics_type_1="EMS"，那么logistics_type_2就只能选择"POST"
			string logistics_fee_2 = string.Empty;                					//物流费用，即运费。
			string logistics_type_2 = string.Empty;               					//物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
			string logistics_payment_2 = string.Empty;            					//物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

			//扩展功能参数——其他
			string buyer_email = string.Empty;                    					//默认买家支付宝账号
			string discount = string.Empty;                       					//折扣，是具体的金额，而不是百分比。若要使用打折，请使用负数，并保证小数点最多两位数

			AlipayClass.AlipayService alipay = new AlipayClass.AlipayService(
				partner,
				seller_email,
				return_url,
				notify_url,
				show_url,
				out_trade_no,
				subject,
				body,
				price,
				logistics_fee,
				logistics_type,
				logistics_payment,
				quantity,
				receive_name,
				receive_address,
				receive_zip,
				receive_phone,
				receive_mobile,
				logistics_fee_1,
				logistics_type_1,
				logistics_payment_1,
				logistics_fee_2,
				logistics_type_2,
				logistics_payment_2,
				buyer_email,
				discount,
				key,
				input_charset,
				sign_type);

			return alipay.Create_url();
		}
	}
}
